﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;

namespace Aandelendelen.Payment
{
	public class IdealCheck : Ideal
	{
		string transactionId;
		int amount;
		string currency;
		string message;
		Consumer consumer;
		string custom = "";
		bool payed = false;
		string returnCode = "";

		public IdealCheck(string partnerId, string transaction_Id)
			: this(partnerId, false, transaction_Id)
		{
		}

		public IdealCheck(string partnerId, bool testMode, string transaction_Id)
			: base(partnerId, testMode)
		{
			Dictionary<string, string> args = new Dictionary<string, string>();
			args["rtlo"] = this.partnerId;
			args["trxid"] = transaction_Id;
			args["once"] = "1";

			//args["partnerid"] = this.partnerId;
			//args["transaction_id"] = transaction_Id;

			this.transactionId = transaction_Id;

			logger.Debug("Handling iDEAL transaction ID: {0}", transaction_Id);

			this.ProcessRequest(this.checkUrl, args);
		}

		protected override void ProcessTargetPayResponse(string response)
		{
			if (response == null)
				throw new Exception("response is null");

			logger.Debug("Response: {0}", response);
			string returnCode = response.Substring(0, 6);
			this.returnCode = returnCode;

			if (returnCode == "000000")
			{
				this.payed = true;

				return;
			}

			switch (returnCode)
			{
				case "TP0010": logger.Error("Transaction in progress...please try again"); break;
				case "TP0011": logger.Error("Transaction cancelled"); break;
				case "TP0012": logger.Error("Transaction expired"); break;
				case "TP0013": logger.Error("Transaction could not be handled"); break;
				case "TP0014": logger.Error("Transaction already handled"); break;
				case "TP0020": logger.Error("Missing layoutcode"); break;
				case "TP0021": logger.Error("Missing transactionID"); break;
				case "TP0022": logger.Error("Transaction not found"); break;
				case "TP0023": logger.Error("Layoutcode doesn't match tranactionID"); break;
				default: logger.Error("Unknown returncode: " + returnCode); break;
			}

			return;
		}

		protected override void ProcessResponse(XmlDocument doc)
		{
			XmlNode orderNode = doc.DocumentElement.FirstChild;

			if (orderNode.Name.ToLower() != "order")
				this.ThrowXmlException(doc);

			foreach (XmlNode childNode in orderNode)
			{
				switch (childNode.Name.ToLower())
				{
					case "transaction_id":
						this.transactionId = childNode.InnerText;
						break;
					case "amount":
						this.amount = XmlConvert.ToInt32(childNode.InnerText);
						break;
					case "currency":
						this.currency = childNode.InnerText;
						break;
					case "payed":
						this.payed = XmlConvert.ToBoolean(childNode.InnerText);
						break;
					case "consumer":
						this.consumer = new Consumer(childNode);
						break;
					case "message":
						this.message = childNode.InnerText;
						break;
					default: this.custom += childNode.OuterXml;
						break;
				}
			}
		}

		public string ReturnCode
		{
			get { return this.returnCode; }
		}

		public string TransactionId
		{
			get { return this.transactionId; }
		}

		public string Currency
		{
			get { return this.currency; }
		}

		public int Amount
		{
			get { return this.amount; }
		}

		public bool Payed
		{
			get { return this.payed; }
		}

		public string Message
		{
			get { return this.message; }
		}

		public Consumer Consumer
		{
			get { return this.consumer; }
		}

		public string Custom
		{
			get { return this.custom; }
		}
	}
}